package com.dana1.nos.impl;


import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import com.dana1.nos.data.AddressExtension;
import com.dana1.nos.data.Branch;
import com.dana1.nos.data.BranchObject;
import com.dana1.nos.data.User;
import com.dana1.nos.old.ObjectKey;
import com.dana1.nos.old.ObjectService;
import com.dana1.nos.old.generator.TimeBasedUUIDGenerator;
import com.dana1.nos.old.impl.memory.MemoryObjectService;

public class TestObjectKeyGeneration
{
	ObjectService os = new MemoryObjectService();
	boolean showKeys = true;

	@Before
	public void setUp() throws Exception
	{
	}

	@Test
	public void testObjectKeyWithInheritance()
	{
		HashMap<String,Comparable<?>> expected = new HashMap<String, Comparable<?>>();
		expected.put("timeStamp",new Timestamp(System.currentTimeMillis()));
		expected.put("userId", (UUID)new TimeBasedUUIDGenerator().nextValue(null));

		User u = os.newInstance(User.class);
		u.setTimeStamp((Timestamp) expected.get("timeStamp"));
		u.setUserId((UUID)expected.get("userId"));
		ObjectKey<?> ok = os.objectKey(u);
		
		if (showKeys) System.out.println(ok);
		expected.put("secureObjectID",ok.getKeyValues().get("secureObjectID"));
		Assert.assertEquals(new ObjectKey<User>(User.class,expected).toString(), ok.toString());
		Assert.assertTrue("Expected a UUID",expected.get("secureObjectID") instanceof UUID);
	}

	@Test 
	public void testObjectKeyForUnsetFields()
	{
		HashMap<String,Comparable<?>> expected = new HashMap<String, Comparable<?>>();
		expected.put("addressId",null);
		expected.put("extensionID", null);

		AddressExtension a = os.newInstance(AddressExtension.class);
		ObjectKey<AddressExtension> ok = os.objectKey(a);
		
		if (showKeys) System.out.println(ok);
		Assert.assertEquals(new ObjectKey<AddressExtension>(AddressExtension.class,expected).toString(), ok.toString());
	}
	 
	
	@Test
	public void testObjectKeyUsingObjectReferences()
	{

		BranchObject bo = os.newInstance(BranchObject.class);
		Branch b = (Branch)os.retrieve(os.insert(os.newInstance(Branch.class)));
		
		
		bo.setBranch(b);
	
		ObjectKey<?> ok = os.objectKey(bo);
		if (showKeys) System.out.println(ok);
		
		Assert.assertTrue("Expected branch_secureObjectID to be a UUID",ok.getKeyValues().get("branch_secureObjectID") instanceof UUID);
		Assert.assertTrue("Expected branch_timeStamp to be a timestamp",ok.getKeyValues().get("branch_timeStamp") instanceof Timestamp);
		Assert.assertNull("branch_branchId should be null", ok.getKeyValues().get("branch_branchId"));
		Assert.assertTrue("OK has exactly 3 keys",ok.getKeyValues().size()==3);

		Map<String,Comparable<?>> bVals = new HashMap<String, Comparable<?>>();
		for (String s: ok.getKeyValues().keySet())
			bVals.put(s.replaceFirst("\\Qbranch_\\E",""),ok.getKeyValues().get(s));
		
		Assert.assertEquals("BranchKey matches mangled BranchObject key",os.objectKey(b).getKeyValues(),bVals);
	}
	
	@Test 
	public void testObjectKeyForUnsetObjectReferences()
	{
		BranchObject bo = os.newInstance(BranchObject.class);
		ObjectKey<BranchObject> ok = os.objectKey(bo);
		if (showKeys) System.out.println(ok);
		Assert.assertEquals("ObjectKey(ServiceObjectClass=interface com.dana1.nos.data.BranchObject,keyValues={branch_branchId=null, branch_secureObjectID=null, branch_timeStamp=null})",ok.toString());
	}


	@After
	public void tearDown() throws Exception
	{
	}

}
